//
//  SlideAnimationController.m
//  CustomNavigationTransition
//
//  Created by 朱志佳 on 2019/4/3.
//  Copyright © 2019 朱志佳. All rights reserved.
//

#import "SlideAnimationController.h"

@implementation SlideAnimationController

// This is used for percent driven interactive transitions, as well as for
// container controllers that have companion animations that might need to
// synchronize with the main animation.
- (NSTimeInterval)transitionDuration:(nullable id <UIViewControllerContextTransitioning>)transitionContext {
    NSLog(@"%@##%@",NSStringFromClass([self class]),NSStringFromSelector(_cmd));
    return 0.3;
}

//// This method can only  be a nop if the transition is interactive and not a percentDriven interactive transition.
- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext {
    NSLog(@"%@##%@",NSStringFromClass([self class]),NSStringFromSelector(_cmd));
    UIView *containerView = [transitionContext containerView];
    UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    
    UIView *fromView = fromVC.view;
    UIView *toView = toVC.view;
    
    CGFloat translation = containerView.frame.size.width;
    CGAffineTransform toViewTransform = CGAffineTransformIdentity;
    CGAffineTransform fromViewTransform = CGAffineTransformIdentity;
    
    switch (_transitionType) {
        case TransitionTypePush:
        case TransitionTypeRight:
        {
            toViewTransform = CGAffineTransformMakeTranslation(translation, 0);
            fromViewTransform = CGAffineTransformMakeTranslation(-translation, 0);
        }
            break;
        case TransitionTypePop:
        case TransitionTypeLeft:
        {
            toViewTransform = CGAffineTransformMakeTranslation(-translation, 0);
            fromViewTransform = CGAffineTransformMakeTranslation(translation, 0);
        }
            break;
        case TransitionTypePresentation:
        {
            translation = containerView.frame.size.height;
            toViewTransform = CGAffineTransformMakeTranslation(0, translation);
            fromViewTransform = CGAffineTransformMakeTranslation(0, 0);
        }
            break;
        case TransitionTypeDismisssal:
        {
            translation = containerView.frame.size.height;
            toViewTransform = CGAffineTransformMakeTranslation(0, -translation);
            fromViewTransform = CGAffineTransformMakeTranslation(0, translation);
        }
            break;
            
        default:
            break;
    }
    
    switch (_transitionType) {
        case TransitionTypePresentation:
            [containerView addSubview:toView];
            break;
        case TransitionTypeDismisssal:
            [containerView addSubview:toView];
            break;
        default:
            [containerView addSubview:toView];
            break;
    }
    
    toView.transform = toViewTransform;
    [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
        fromView.transform = fromViewTransform;
        toView.transform = CGAffineTransformIdentity;
    } completion:^(BOOL finished) {
        fromView.transform = CGAffineTransformIdentity;
        toView.transform = CGAffineTransformIdentity;
        /* 转场的结果有两种：完成或取消。非交互转场的结果只有完成一种情况，不过交互式转场需要考虑取消的情况。如何结束取决于转场的进度，通过[transitionContext transitionWasCancelled]方法来获取转场的结果，然后使用completeTransition:来通知系统转场过程结束，这个方法会检查动画控制器是否实现了animationEnded:方法，如果有，则调用该方法*/
        BOOL isCancelled = [transitionContext transitionWasCancelled];
        [transitionContext completeTransition:!isCancelled];
    }];
}

/// A conforming object implements this method if the transition it creates can
/// be interrupted. For example, it could return an instance of a
/// UIViewPropertyAnimator. It is expected that this method will return the same
/// instance for the life of a transition.
//- (id <UIViewImplicitlyAnimating>) interruptibleAnimatorForTransition:(id <UIViewControllerContextTransitioning>)transitionContext NS_AVAILABLE_IOS(10_0);

// This is a convenience and if implemented will be invoked by the system when the transition context's completeTransition: method is invoked.
- (void)animationEnded:(BOOL) transitionCompleted{
    NSLog(@"%@##%@",NSStringFromClass([self class]),NSStringFromSelector(_cmd));
}

@end
